package org.jivesoftware.smack;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.FromContainsFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.ThreadFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Message.Type;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.collections.ReferenceMap;

public class ChatManager
{
  private static long id;
  private static String prefix = StringUtils.randomString(5);
  private Set<ChatManagerListener> chatManagerListeners;
  private Connection connection;
  private Map<PacketInterceptor, PacketFilter> interceptors;
  private Map<String, Chat> jidChats;
  private Map<String, Chat> threadChats = new ReferenceMap(0, 2);

  static
  {
    id = 0L;
  }

  ChatManager(Connection paramConnection)
  {
    this.jidChats = new ReferenceMap(0, 2);
    this.chatManagerListeners = new CopyOnWriteArraySet();
    this.interceptors = new WeakHashMap();
    this.connection = paramConnection;
    1 local1 = new PacketFilter(this)
    {
      public boolean accept()
      {
        int i;
        if (!(paramPacket instanceof Message))
          i = 0;
        while (true)
        {
          while (true)
          {
            return i;
            Message.Type localType = ((Message)paramPacket).getType();
            if ((localType == Message.Type.groupchat) || (localType == Message.Type.headline))
              break;
            i = 1;
          }
          i = 0;
        }
      }
    };
    paramConnection.addPacketListener(new PacketListener(this)
    {
      public void processPacket()
      {
        Chat localChat;
        Message localMessage = (Message)paramPacket;
        if (localMessage.getThread() == null)
          localChat = ChatManager.access$0(this.this$0, localMessage.getFrom());
        while (true)
        {
          do
          {
            if (localChat == null)
              localChat = ChatManager.access$1(this.this$0, localMessage);
            ChatManager.access$2(this.this$0, localChat, localMessage);
            return;
            localChat = this.this$0.getThreadChat(localMessage.getThread());
          }
          while (localChat != null);
          localChat = ChatManager.access$0(this.this$0, localMessage.getFrom());
        }
      }
    }
    , local1);
  }

  private Chat createChat(String paramString1, String paramString2, boolean paramBoolean)
  {
    Chat localChat = new Chat(this, paramString1, paramString2);
    this.threadChats.put(paramString2, localChat);
    this.jidChats.put(paramString1, localChat);
    Iterator localIterator = this.chatManagerListeners.iterator();
    while (true)
    {
      if (!(localIterator.hasNext()))
        return localChat;
      ((ChatManagerListener)localIterator.next()).chatCreated(localChat, paramBoolean);
    }
  }

  private Chat createChat(Message paramMessage)
  {
    String str = paramMessage.getThread();
    if (str == null)
      str = nextID();
    return createChat(paramMessage.getFrom(), str, false);
  }

  private void deliverMessage(Chat paramChat, Message paramMessage)
  {
    paramChat.deliver(paramMessage);
  }

  private Chat getUserChat(String paramString)
  {
    return ((Chat)this.jidChats.get(paramString));
  }

  /**
   * @deprecated
   */
  private static String nextID()
  {
    monitorenter;
    try
    {
      StringBuilder localStringBuilder = new StringBuilder(String.valueOf(prefix));
      long l = id;
      id = 1L + l;
      String str = Long.toString(l);
      monitorexit;
      return str;
    }
    finally
    {
      localObject = finally;
      monitorexit;
      throw localObject;
    }
  }

  public void addChatListener(ChatManagerListener paramChatManagerListener)
  {
    this.chatManagerListeners.add(paramChatManagerListener);
  }

  public void addOutgoingMessageInterceptor(PacketInterceptor paramPacketInterceptor)
  {
    addOutgoingMessageInterceptor(paramPacketInterceptor, null);
  }

  public void addOutgoingMessageInterceptor(PacketInterceptor paramPacketInterceptor, PacketFilter paramPacketFilter)
  {
    if (paramPacketInterceptor != null)
      this.interceptors.put(paramPacketInterceptor, paramPacketFilter);
  }

  public Chat createChat(String paramString1, String paramString2, MessageListener paramMessageListener)
  {
    if (paramString2 == null)
      paramString2 = nextID();
    if ((Chat)this.threadChats.get(paramString2) != null)
      throw new IllegalArgumentException("ThreadID is already used");
    Chat localChat = createChat(paramString1, paramString2, true);
    localChat.addMessageListener(paramMessageListener);
    return localChat;
  }

  public Chat createChat(String paramString, MessageListener paramMessageListener)
  {
    String str;
    do
      str = nextID();
    while (this.threadChats.get(str) != null);
    return createChat(paramString, str, paramMessageListener);
  }

  PacketCollector createPacketCollector(Chat paramChat)
  {
    Connection localConnection = this.connection;
    PacketFilter[] arrayOfPacketFilter = new PacketFilter[2];
    arrayOfPacketFilter[0] = new ThreadFilter(paramChat.getThreadID());
    arrayOfPacketFilter[1] = new FromContainsFilter(paramChat.getParticipant());
    return localConnection.createPacketCollector(new AndFilter(arrayOfPacketFilter));
  }

  public Collection<ChatManagerListener> getChatListeners()
  {
    return Collections.unmodifiableCollection(this.chatManagerListeners);
  }

  public Chat getThreadChat(String paramString)
  {
    return ((Chat)this.threadChats.get(paramString));
  }

  public void removeChatListener(ChatManagerListener paramChatManagerListener)
  {
    this.chatManagerListeners.remove(paramChatManagerListener);
  }

  void sendMessage(Chat paramChat, Message paramMessage)
  {
    Iterator localIterator = this.interceptors.entrySet().iterator();
    while (true)
    {
      Map.Entry localEntry;
      PacketFilter localPacketFilter;
      do
      {
        if (!(localIterator.hasNext()))
        {
          if (paramMessage.getFrom() == null)
            paramMessage.setFrom(this.connection.getUser());
          this.connection.sendPacket(paramMessage);
          return;
        }
        localEntry = (Map.Entry)localIterator.next();
        localPacketFilter = (PacketFilter)localEntry.getValue();
      }
      while ((localPacketFilter == null) || (!(localPacketFilter.accept(paramMessage))));
      ((PacketInterceptor)localEntry.getKey()).interceptPacket(paramMessage);
    }
  }
}